#ifndef TCP_SERVER_THREADPOOL_H
#define TCP_SERVER_THREADPOOL_H

#include "Mutex.h"
#include "Thread.h"
#include "../Types.h"
#include "../noncopyable.h"

#include <deque>
#include <vector>
#include <memory>

class ThreadPool : muduo::noncopyable {
public:
    typedef std::function<void()> Task;
    // 线程任务

    explicit ThreadPool(string nameArg = string("ThreadPool"));

    ~ThreadPool();

    // Must be called before start().
    void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; }

    void setThreadInitCallback(const Task &cb) { threadInitCallback_ = cb; }

    void start(int numThreads);

    void stop();

    const string &name() const { return name_; }

    size_t queueSize() const;

    void run(Task f);

private:
    /**
     * 检查线程池是否满了
     * @return 返回是否满
     */
    bool isFull() const;

    /**
     * 运行线程任务
     */
    void runInThread();

    /**
     * 获取线程任务函数指针
     */
    Task take();

    mutable MutexLock mutex_;
    // 这里被mutable修饰的变量将一直处于可变状态, 哪怕是位于const修饰的函数中
    Condition notEmpty_;
    // 用于在任务队列为空的时候阻塞线程池中的线程用
    Condition notFull_;
    // 用于在任务队列已满的情况下阻塞等待任务队列有空位
    string name_;
    Task threadInitCallback_;
    // 线程初始化时调用的函数
    std::vector<std::unique_ptr<Thread>> threads_;
    // 线程池管理
    std::deque<Task> queue_;
    // 任务队列
    size_t maxQueueSize_;
    // 最大的队列长度
    bool running_;
    // 是否在运行中
};

#endif //TCP_SERVER_THREADPOOL_H
